#pragma once
#include <memory>
#include <thread>
#include <vector>

#include "client/rpc_client.h"
#include "monitor/cpu_load_monitor.h"
#include "monitor/cpu_softirq_monitor.h"
#include "monitor/cpu_stat_monitor.h"
#include "monitor/mem_monitor.h"
#include "monitor/monitor_inter.h"
#include "monitor/net_monitor.h"

#include "monitor_info.grpc.pb.h"
#include "monitor_info.pb.h"

int main() {
  // 抽象工厂是MonitorInter ，具体工厂是下面CpuSoftIrqMonitor 等
  std::vector<std::shared_ptr<monitor::MonitorInter>> runners_;
  // 工厂进行生产。
  runners_.emplace_back(new monitor::CpuSoftIrqMonitor());   
  runners_.emplace_back(new monitor::CpuLoadMonitor());
  runners_.emplace_back(new monitor::CpuStatMonitor());
  runners_.emplace_back(new monitor::MemMonitor());
  runners_.emplace_back(new monitor::NetMonitor());

  monitor::RpcClient rpc_client_;
  char *name = getenv("USER"); // 获取当前用户
  std::unique_ptr<std::thread> thread_ = nullptr; // 
  // 下面的语句相当于创建线程 ： thread_ = std::make_unique<std::thread> (thread_func) 
  thread_ = std::make_unique<std::thread>([&]() {  // 因为要使用局部变量所以用 & 引用来避免局部变量的拷贝 。  
    while (true) {
      monitor::proto::MonitorInfo monitor_info;
      monitor_info.set_name(std::string(name));
      for (auto& runner : runners_) {
        runner->UpdateOnce(&monitor_info);
      }
      rpc_client_.SetMonitorInfo(monitor_info); // 更新设置monitor的信息 
      std::this_thread::sleep_for(std::chrono::seconds(3)); // 睡3秒 。 每三秒读取一下信息 。
    }
  }); // 使用了匿名函数每三秒执行一次。 

  thread_->join();
  return 0;
}
